<template>
  <div
    ref="dropdownWrapperRef"
    class="toolbar-dropdown-wrapper"
    :class="{
      'toolbar-dropdown-horizontal': isSimpleMode && showDropdownLabel
    }"
    tabindex="0"
    @blur="handleTriggerBlur"
  >
    <div class="toolbar-dropdown-icons-wrapper">
      <!-- 主图标按钮 -->
      <ToolbarButton
        ref="mainButtonRef"
        v-bind="mainButtonAttrs"
        :class="['toolbar-dropdown-main-button', mainButtonClass]"
        @click="handleMainClick"
      >
        <template v-if="$slots.icon" #icon>
          <slot name="icon"></slot>
        </template>
        <template v-else #default>
          <slot></slot>
        </template>
      </ToolbarButton>

      <!-- 下拉箭头按钮 -->
      <DropdownMenu
        ref="dropdownMenuRef"
        v-bind="dropdownMenuAttrs"
      >
        <button
          class="toolbar-dropdown-trigger-button"
          :class="triggerButtonClass"
          :disabled="disabled"
          @click.stop
        >
          <div :class="dropdownIconClass" :style="dropdownIconStyle"></div>
        </button>
        <template #menu>
          <slot name="dropdown"></slot>
        </template>
      </DropdownMenu>
    </div>
    
    <!-- 文字标签 -->
    <span v-if="showDropdownLabel" class="toolbar-dropdown-label">{{ titleValue }}</span>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  onBeforeUnmount,
  onMounted,
  ref,
  useAttrs,
  inject,
} from "vue";
import type { CSSProperties } from "vue";
import type { DropdownProps } from "./button.types";
import ToolbarButton from "./Button.vue";
import { DropdownMenu } from "../../dropdown";
import type { EditorProps } from "../../../types";
import { useState } from "../../../store";
import {
  onCloseAllToolbarPopups,
  type CloseAllToolbarPopupsEventDetail,
} from "./utils/toolbarPopupManager";

defineOptions({
  inheritAttrs: false,
  name: "ToolbarDropdown",
});

const props = withDefaults(defineProps<DropdownProps>(), {
  placement: "bottom",
  trigger: "click",
  disabled: false,
  hideText: true,
  dropdownIcon: "i-ri-arrow-down-s-fill",
});

const emit = defineEmits<{
  (e: "main-click", event: MouseEvent): void;
  (e: "dropdown-click"): void;
}>();

const attrs = useAttrs();
const mainButtonRef = ref<InstanceType<typeof ToolbarButton>>();
const dropdownMenuRef = ref<InstanceType<typeof DropdownMenu> | null>(null);
const dropdownWrapperRef = ref<HTMLDivElement>();

// 注入编辑器配置
const injectedEditorProps = inject<EditorProps | undefined>("editorProps");
const toolbarState = injectedEditorProps ? useState("toolbar", { value: injectedEditorProps }) : null;

// 判断是否为 simple 模式
const isSimpleMode = computed(() => {
  if (!toolbarState) return false;
  const mode = toolbarState.value?.mode;
  return mode === "simple";
});

// 驼峰转短横线
const camelToKebab = (str: string): string => {
  return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
};

// 从 attrs 中获取属性值
const getAttrValue = <T>(key: string, defaultValue?: T): T | undefined => {
  // 先尝试直接获取
  if (attrs[key] !== undefined) {
    return attrs[key] as T;
  }
  // 再尝试驼峰转短横线格式
  const kebabKey = camelToKebab(key);
  if (attrs[kebabKey] !== undefined) {
    return attrs[kebabKey] as T;
  }
  return defaultValue;
};

// 提取主按钮相关的属性
const mainButtonAttrs = computed(() => {
  const iconValue = getAttrValue<string>("icon");
  return {
    // 只有当明确提供了 icon 时才传递，否则不传递让 Button 显示 default 插槽
    ...(iconValue ? { icon: iconValue } : {}),
    title: getAttrValue<string>("title"),
    largeIcon: getAttrValue<boolean>("largeIcon", false),
    active: getAttrValue<boolean>("active", false),
    disabled: props.disabled,
    hideText: true, // 主按钮始终隐藏文字，文字显示在外部标签
    round: getAttrValue<boolean>("round", false),
    circle: getAttrValue<boolean>("circle", false),
  };
});

// 主按钮类名
const mainButtonClass = computed(() => ({
  "is-disabled": props.disabled,
}));

// 下拉箭头按钮类名
const triggerButtonClass = computed(() => ({
  "is-disabled": props.disabled,
}));

// 下拉图标类名
const dropdownIconClass = computed(() => {
  return props.dropdownIcon || "i-ri-arrow-down-s-fill";
});

// 下拉图标样式
const dropdownIconStyle = computed(() => {
  // 下拉箭头图标始终使用小尺寸，只设置字体大小，让 CSS 控制尺寸
  return {
    fontSize: "11px",
    lineHeight: "1",
  };
});

// 标题值
const titleValue = computed(() => {
  return getAttrValue<string>("title") || "";
});

// 是否显示下拉标签
const showDropdownLabel = computed(() => {
  return !!(titleValue.value && !props.hideText);
});

// DropdownMenu 的 trigger 类型转换（只支持 click 或 hover）
const dropdownTrigger = computed<"click" | "hover">(() => {
  const trigger = props.trigger || "click";
  if (trigger === "click" || trigger === "hover") {
    return trigger;
  }
  return "click";
});

// DropdownMenu 的 customStyle 类型转换
const dropdownCustomStyle = computed<CSSProperties | undefined>(() => {
  const style = getAttrValue<string | CSSProperties>("customStyle");
  if (typeof style === "string") {
    return undefined;
  }
  return style;
});

// DropdownMenu 属性
const dropdownMenuAttrs = computed(() => ({
  placement: props.placement,
  trigger: dropdownTrigger.value,
  disabled: props.disabled,
  "custom-class": getAttrValue<string>("customClass", ""),
  "custom-style": dropdownCustomStyle.value,
}));

// 处理主按钮点击
const handleMainClick = (event: MouseEvent) => {
  event.stopPropagation();
  event.preventDefault();
  
  // 点击主按钮时切换下拉菜单
  if (dropdownMenuRef.value) {
    const menuInstance = dropdownMenuRef.value as any;
    if (menuInstance.toggle) {
      menuInstance.toggle();
    }
  }
  
  emit("main-click", event);
};

// 处理触发器失焦事件
const handleTriggerBlur = (event: FocusEvent) => {
  // 如果焦点移到了 dropdown 内容区域，不关闭
  const relatedTarget = event.relatedTarget as Node | null;
  if (relatedTarget) {
    // 检查是否在下拉菜单内
    const menuElement = dropdownMenuRef.value
      ? (dropdownMenuRef.value as any)?.floatingRef
      : null;
    if (menuElement && menuElement.contains(relatedTarget)) {
      return;
    }
  }
};

// 监听关闭所有弹窗的事件
const handleCloseAllPopups = (
  event: CustomEvent<CloseAllToolbarPopupsEventDetail>
) => {
  const { currentInstance, excludeTypes } = event.detail;
  // 如果当前实例不是当前 Dropdown，或者被排除，则关闭
  if (
    currentInstance !== dropdownWrapperRef.value &&
    !excludeTypes?.includes("dropdown") &&
    dropdownMenuRef.value
  ) {
    if ((dropdownMenuRef.value as any).visible) {
      dropdownMenuRef.value.toggle();
    }
  }
};

let cleanupPopupListener: (() => void) | null = null;

// 在组件挂载时添加事件监听
onMounted(() => {
  cleanupPopupListener = onCloseAllToolbarPopups(handleCloseAllPopups);
});

// 在组件卸载时移除事件监听
onBeforeUnmount(() => {
  if (cleanupPopupListener) {
    cleanupPopupListener();
    cleanupPopupListener = null;
  }
});
</script>

<style scoped>
.toolbar-dropdown-wrapper {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  margin: 0 2px;
  background-color: transparent;
  transition: background-color 0.1s ease;
  gap: 0;
  border-radius: var(--editor-radius-medium, 4px);
  padding: 2px;
}

/* Simple 模式下的水平布局（当 hideText 为 false 时） */
.toolbar-dropdown-wrapper.toolbar-dropdown-horizontal {
  flex-direction: row !important;
  align-items: center;
  gap: 2px;
  min-width: auto;
}

/* 整体 hover 效果 - 整个区域都有背景 */
.toolbar-dropdown-wrapper:not(:has(.is-disabled)):hover {
  background-color: var(--editor-button-hover-background, rgba(0, 0, 0, 0.06));
}

/* 图标和下拉箭头容器 - 统一为一个整体按钮，紧凑排列 */
.toolbar-dropdown-icons-wrapper {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  border-radius: var(--editor-radius-medium, 4px);
  background-color: transparent;
  transition: background-color 0.1s ease;
  overflow: hidden;
  gap: 0;
}

/* 主图标按钮区域 - 完全透明，让 ToolbarButton 处理样式 */
.toolbar-dropdown-main-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-color: transparent;
  border: none;
  padding: 0;
  margin: 0;
}

/* 禁用主按钮自身的 hover 效果，由 wrapper 统一处理 */
.toolbar-dropdown-wrapper:not(:has(.is-disabled)):hover .toolbar-dropdown-main-button:not(.is-disabled):hover {
  background-color: transparent;
}

/* 下拉触发按钮 - 极简设计，与主按钮无缝融合，紧凑 */
.toolbar-dropdown-trigger-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 2px;
  height: 100%;
  font-size: 12px;
  color: var(--editor-text-color, #333);
  background-color: transparent;
  border: none;
  cursor: pointer;
  transition: background-color 0.1s ease;
  outline: none;
  position: relative;
  margin-left: -1px; /* 让下拉按钮与主按钮更紧密 */
}

/* 极细的分隔线，仅在 hover 时显示 */
.toolbar-dropdown-trigger-button::before {
  content: "";
  position: absolute;
  left: 0;
  top: 30%;
  bottom: 30%;
  background-color: var(--editor-border-color-light, rgba(0, 0, 0, 0.1));
  opacity: 0;
  transition: opacity 0.1s ease;
}

.toolbar-dropdown-wrapper:not(:has(.is-disabled)):hover .toolbar-dropdown-trigger-button::before {
  opacity: 0.5;
}

/* 禁用下拉箭头按钮自身的 hover 效果，由 wrapper 统一处理 */
.toolbar-dropdown-wrapper:not(:has(.is-disabled)):hover .toolbar-dropdown-trigger-button:not(.is-disabled):hover {
  background-color: transparent;
}

.toolbar-dropdown-trigger-button:not(.is-disabled):active {
  background-color: var(--editor-button-active-background, rgba(0, 0, 0, 0.12));
}

.toolbar-dropdown-trigger-button.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  color: var(--editor-text-color-disabled, #999);
  pointer-events: none;
}

/* 下拉图标 - 更小的尺寸，更精致 */
.toolbar-dropdown-trigger-button [class*="i-"] {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  line-height: 1;
  transition: opacity 0.1s ease;
}

.toolbar-dropdown-trigger-button:not(.is-disabled):hover [class*="i-"] {
  opacity: 0.8;
}

/* 文字标签 - 紧凑间距 */
.toolbar-dropdown-label {
  display: block;
  width: 100%;
  font-size: var(--editor-font-size-small, 12px);
  line-height: 1.2;
  color: var(--editor-text-color, #333);
  white-space: nowrap;
  user-select: none;
  text-align: center;
  margin-top: 1px;
  padding: 0;
}

/* Simple 模式下的水平布局时，文字标签在右侧，紧凑 */
.toolbar-dropdown-wrapper.toolbar-dropdown-horizontal .toolbar-dropdown-label {
  width: auto !important;
  margin-top: 0 !important;
  margin-left: 2px;
  text-align: left;
}
</style>

